<template>
  <el-drawer v-model="drawerVisible" :destroy-on-close="true" size="450px" :title="`${drawerProps.title}菜单`">
    <el-form
      ref="ruleFormRef"
      label-width="100px"
      label-suffix=" :"
      :rules="rules"
      :disabled="drawerProps.isView"
      :model="drawerProps.row"
      :hide-required-asterisk="drawerProps.isView"
    >
      <el-form-item label="父级路由">
        <el-button @click="showRouteList">选择父级路由</el-button>
        <!-- 在按钮旁边展示选定的路由 -->
        <el-tag size="large" v-if="selectedRoute" type="success">{{ selectedRoute.label }}</el-tag>
        <el-tag size="large" v-else type="info">未选择 则为顶级路由</el-tag>
        <el-dialog v-model="dialogVisible" :destroy-on-close="true" title="路由列表" width="50%">
          <el-tree
            :data="treeData"
            v-model="selectedRoute"
            node-key="id"
            :show-checkbox="false"
            accordion
            :default-expand-all="true"
            :indent="16"
            @node-click="handleNodeClick"
          />
        </el-dialog>
      </el-form-item>
      <el-form-item label="菜单名称" prop="title">
        <el-input v-model="drawerProps.row!.title" placeholder="请填写菜单名称" clearable></el-input>
      </el-form-item>
      <el-form-item label="菜单图标" prop="icon">
        <el-select v-model="drawerProps.row!.icon" clearable placeholder="请选择图标">
          <el-option v-for="item in icons" :key="item" :value="item">
            <el-icon size="18">
              <component :is="item"></component>
            </el-icon>
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="菜单 name" prop="name">
        <el-input v-model="drawerProps.row!.name" placeholder="请填写菜单 name" clearable></el-input>
      </el-form-item>
      <el-form-item label="按钮权限">
        <el-checkbox-group v-model="drawerProps.row!.authButtons">
          <el-checkbox v-for="button in allButtons" :label="button.id" :key="button.id"> {{ button.buttonAuth }} </el-checkbox>
        </el-checkbox-group>
      </el-form-item>
      <el-form-item label="菜单路径" prop="path">
        <el-input v-model="drawerProps.row!.path" placeholder="请填写菜单路径" clearable></el-input>
      </el-form-item>
      <el-form-item label="组件路径" prop="component">
        <el-input v-model="componentValue" placeholder="请填写组件路径" clearable></el-input>
      </el-form-item>
      <el-form-item label="重定向路径" prop="redirect">
        <el-input v-model="drawerProps.row!.redirect" placeholder="请填写重定向路径" clearable></el-input>
      </el-form-item>
      <el-form-item label="activeMenu" prop="activeMenu">
        <el-input v-model="drawerProps.row!.activeMenu" placeholder="请填写activeMenu" clearable></el-input>
      </el-form-item>
      <el-form-item label="链接" prop="link">
        <el-input v-model="drawerProps.row!.isLink" placeholder="请填写链接" clearable></el-input>
      </el-form-item>
      <el-form-item label="是否隐藏">
        <el-switch v-model="drawerProps.row!.isHide" active-text="True" inactive-text="False"></el-switch>
      </el-form-item>
      <el-form-item label="是否铺满">
        <el-switch v-model="drawerProps.row!.isFull" active-text="True" inactive-text="False"></el-switch>
      </el-form-item>
      <el-form-item label="是否Affix">
        <el-switch v-model="drawerProps.row!.isAffix" active-text="True" inactive-text="False"></el-switch>
      </el-form-item>
      <el-form-item label="KeepAlive">
        <el-switch v-model="drawerProps.row!.isKeepAlive" active-text="True" inactive-text="False"></el-switch>
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button @click="drawerVisible = false">取消</el-button>
      <el-button v-show="!drawerProps.isView" type="primary" @click="handleSubmit">确定</el-button>
    </template>
  </el-drawer>
</template>

<script setup lang="ts" name="MenuDrawer">
import { ref, reactive, computed } from "vue";
import { ElMessage, FormInstance } from "element-plus";
import { getMenuList } from "@/api/modules/menu";
import { Button } from "@/api/interface";
import { getButtonList } from "@/api/modules/button";
import { useAuthStore } from "@/stores/modules/auth";

const rules = reactive({
  title: [{ required: true, message: "请填写菜单名称" }],
  icon: [{ required: true, message: "请选择图标" }],
  name: [{ required: true, message: "请填写菜单 name" }],
  // component: [
  //   { required: false, message: "请填写组件路径" },
  //   {
  //     validator: customPathValidator,
  //     message: "路径应以 '/' 开头"
  //   }
  // ],
  path: [
    { required: true, message: "请填写菜单路径" },
    {
      validator: customPathValidator,
      message: "路径应以 '/' 开头"
    }
  ]
});
// 计算属性，根据 drawerProps.row!.component 的类型返回一个合适的值
const componentValue = computed({
  get: () => {
    // 获取 drawerProps.row!.component 的值
    const value = drawerProps.value.row!.component;

    // 如果是函数或者 undefined，则返回空字符串
    if (typeof value === "function" || value === undefined) {
      return "";
    }

    // 否则返回实际的值
    return value;
  },
  set: (newValue: string) => {
    // 设置 drawerProps.row!.component 的值
    drawerProps.value.row!.component = newValue;
  }
});

const dialogVisible = ref(false);

const showRouteList = () => {
  // 在这里处理打开模态框的逻辑
  dialogVisible.value = true;
  console.log(dialogVisible.value);
};

const selectedRoute = ref<TreeData | null>(null);

const handleNodeClick = (node: TreeData) => {
  // 处理节点点击事件，将选择的节点存储在 selectedRoute 中
  selectedRoute.value = node;
  drawerProps.value.row.parentId = node.id;
  dialogVisible.value = false;
};

// 递归过滤子项
function filterTree(menuList: TreeData[], targetId: number | null | undefined): void {
  for (let i = menuList.length - 1; i >= 0; i--) {
    const menu = menuList[i];

    if (menu.id === targetId) {
      // 过滤掉当前项
      menuList.splice(i, 1);
      continue;
    }

    if (menu.children && menu.children.length > 0) {
      // 递归过滤子项
      filterTree(menu.children, targetId);

      // 如果当前项的子项全部被过滤，也过滤掉当前项
      if (menu.children.length === 0) {
        menuList.splice(i, 1);
      }
    }
  }
}

interface TreeData {
  id: number;
  label: string;
  children?: TreeData[];
}

// 递归转换函数
function convertMenuListToTreeData(menuList: Menu.MenuOptions[]): TreeData[] {
  return menuList.map(menu => ({
    id: menu.id,
    label: menu.meta.title,
    children: menu.children ? convertMenuListToTreeData(menu.children) : []
  }));
}

const menuList = ref<Menu.MenuOptions[]>([]);
const treeData = ref<TreeData[]>([]);
const getMenus = async () => {
  try {
    const { data } = await getMenuList({ component: null, path: null, title: null });
    console.log(data.list);
    menuList.value = data.list;
    // 使用递归函数进行转换
    treeData.value = convertMenuListToTreeData(menuList.value);
    if (drawerProps.value.row.parentId) {
      console.log(" 父节点 " + drawerProps.value.row.parentId);
      console.log(" 当前所有节点 " + treeData.value);
      selectedRoute.value = findNodeById(treeData.value, drawerProps.value.row.parentId);
    } else {
      selectedRoute.value = null;
    }
    if (drawerProps.value.title === "编辑") {
      // 过滤当前项及其所有子项
      filterTree(treeData.value, drawerProps.value.row.id);
    }
    console.log(drawerProps.value);
    console.log(treeData.value);
  } catch (error) {
    console.error("Error fetching permission list:", error);
  }
};

const allButtons = ref<Button.ResButton[]>([]);
const getButtons = async () => {
  const { data } = await getButtonList({});
  allButtons.value = data.list;
};

// 查找匹配的节点
function findNodeById(nodes: TreeData[], id: number): TreeData | null {
  for (const node of nodes) {
    if (node.id === id) {
      return node;
    } else if (node.children && node.children.length > 0) {
      const matchedChild = findNodeById(node.children, id);
      if (matchedChild) {
        return matchedChild;
      }
    }
  }
  return null;
}

// 自定义路径验证函数
function customPathValidator(rule: any, value: string, callback: (error?: string) => void) {
  // 进行自定义验证逻辑，调用 callback 传递验证结果
  if (value.startsWith("/")) {
    callback();
  } else {
    callback("路径应以 '/' 开头");
  }
}

const icons = ref<string[]>([
  "Goods",
  "Plus",
  "Minus",
  "CirclePlus",
  "Search",
  "Female",
  "Male",
  "Aim",
  "House",
  "FullScreen",
  "Loading",
  "Link",
  "Service",
  "Pointer",
  "Star",
  "Notification",
  "Connection",
  "ChatDotRound",
  "Setting",
  "Clock",
  "Position",
  "Discount",
  "Odometer",
  "ChatSquare",
  "ChatRound",
  "ChatLineRound",
  "ChatLineSquare",
  "ChatDotSquare",
  "View",
  "Hide",
  "Unlock",
  "Lock",
  "RefreshRight",
  "RefreshLeft",
  "Refresh",
  "Bell",
  "MuteNotification",
  "User",
  "Check",
  "CircleCheck",
  "Warning",
  "CircleClose",
  "Close",
  "PieChart",
  "More",
  "Compass",
  "Filter",
  "Switch",
  "Select",
  "SemiSelect",
  "CloseBold",
  "EditPen",
  "Edit",
  "Message",
  "MessageBox",
  "TurnOff",
  "Finished",
  "Delete",
  "Crop",
  "SwitchButton",
  "Operation",
  "Open",
  "Remove",
  "ZoomOut",
  "ZoomIn",
  "InfoFilled",
  "CircleCheckFilled",
  "SuccessFilled",
  "WarningFilled",
  "CircleCloseFilled",
  "QuestionFilled",
  "WarnTriangleFilled",
  "UserFilled",
  "MoreFilled",
  "Tools",
  "HomeFilled",
  "Menu",
  "UploadFilled",
  "Avatar",
  "HelpFilled",
  "Share",
  "StarFilled",
  "Comment",
  "Histogram",
  "Grid",
  "Promotion",
  "DeleteFilled",
  "RemoveFilled",
  "CirclePlusFilled"
]);

interface DrawerProps {
  title: string;
  isView: boolean;
  row: Partial<Menu.EditOrAddMenu>;
  api?: (params: any) => Promise<any>;
  getTableList?: () => void;
}

const drawerVisible = ref(false);
const drawerProps = ref<DrawerProps>({
  isView: false,
  title: "",
  row: {}
});

// 接收父组件传过来的参数
const acceptParams = (params: DrawerProps) => {
  drawerProps.value = params;
  console.log(params);
  drawerVisible.value = true;
  getMenus();
  getButtons();
};

// 提交数据（新增/编辑）
const ruleFormRef = ref<FormInstance>();
const authStore = useAuthStore();
const handleSubmit = () => {
  ruleFormRef.value!.validate(async valid => {
    if (!valid) return;
    try {
      await drawerProps.value.api!(drawerProps.value.row);
      ElMessage.success({ message: `${drawerProps.value.title}菜单成功！` });
      // 刷新当前菜单
      await authStore.getAuthMenuList();
      // 刷新按钮
      await authStore.getAuthButtonList();
      drawerProps.value.getTableList!();
      drawerVisible.value = false;
    } catch (error) {
      console.log(error);
    }
  });
};

defineExpose({
  acceptParams
});
</script>
